<script setup lang="ts">
import type { FormInstance } from 'ant-design-vue';

import type { User } from '#/api';

import { computed, reactive, ref, watch } from 'vue';

import {
  Form,
  FormItem,
  Input,
  InputPassword,
  message,
  Modal,
  Radio,
  RadioGroup,
  Select,
} from 'ant-design-vue';

import { addUserApi, updateUserApi } from '#/api';
import { prepareCreateData, prepareUpdateData } from '#/utils/form';

interface Props {
  visible: boolean;
  userData?: User;
}

const props = defineProps<Props>();
const emit = defineEmits(['update:visible', 'success']);

const formRef = ref<FormInstance>();
const confirmLoading = ref(false);

// 是否编辑模式
const isEdit = computed(() => !!props.userData?.id);

// 表单数据
const formData = reactive<User>({
  id: undefined,
  username: '',
  password: '',
  nickname: '',
  email: '',
  phone: '',
  gender: undefined,
  status: 1,
});

// 表单验证规则
const rules = {
  username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
  password: [
    {
      required: true,
      message: '请输入密码',
      trigger: 'blur',
      validator: (_rule: any, value: string) => {
        if (isEdit.value) {
          return Promise.resolve();
        }
        if (!value) {
          return Promise.reject(new Error('请输入密码'));
        }
        if (value.length < 6) {
          return Promise.reject(new Error('密码长度不能少于6位'));
        }
        return Promise.resolve();
      },
    },
  ],
  email: [
    {
      type: 'email',
      message: '请输入正确的邮箱格式',
      trigger: 'blur',
    },
  ],
  phone: [
    {
      pattern: /^1[3-9]\d{9}$/,
      message: '请输入正确的手机号格式',
      trigger: 'blur',
    },
  ],
  status: [{ required: true, message: '请选择状态', trigger: 'change' }],
};

// 监听用户数据变化
watch(
  () => props.userData,
  (newVal) => {
    if (newVal) {
      Object.assign(formData, newVal);
    } else {
      resetForm();
    }
  },
  { immediate: true },
);

// 重置表单
function resetForm() {
  formData.id = undefined;
  formData.username = '';
  formData.password = '';
  formData.nickname = '';
  formData.email = '';
  formData.phone = '';
  formData.gender = undefined;
  formData.status = 1;
  formRef.value?.clearValidate();
}

// 确定
async function handleOk() {
  try {
    await formRef.value?.validate();
    confirmLoading.value = true;

    if (isEdit.value) {
      // 编辑时，移除密码字段和审计字段
      const { password: _password, ...updateData } = formData;
      await updateUserApi(prepareUpdateData(updateData) as User);
      message.success('编辑成功');
    } else {
      // 新增时，移除审计字段和 id
      await addUserApi(prepareCreateData(formData) as User);
      message.success('新增成功');
    }

    emit('success');
    handleCancel();
  } catch (error) {
    // 验证失败或请求失败
    console.error('保存用户失败:', error);
  } finally {
    confirmLoading.value = false;
  }
}

// 取消
function handleCancel() {
  emit('update:visible', false);
  resetForm();
}
</script>

<template>
  <Modal
    :visible="visible"
    :title="isEdit ? '编辑用户' : '新增用户'"
    :confirm-loading="confirmLoading"
    @ok="handleOk"
    @cancel="handleCancel"
  >
    <Form
      ref="formRef"
      :model="formData"
      :rules="rules"
      :label-col="{ span: 6 }"
      :wrapper-col="{ span: 16 }"
    >
      <FormItem label="用户名" name="username">
        <Input
          v-model:value="formData.username"
          placeholder="请输入用户名"
          :disabled="isEdit"
        />
      </FormItem>

      <FormItem v-if="!isEdit" label="密码" name="password">
        <InputPassword
          v-model:value="formData.password"
          placeholder="请输入密码（至少6位）"
        />
      </FormItem>

      <FormItem label="昵称" name="nickname">
        <Input
          v-model:value="formData.nickname"
          placeholder="请输入昵称"
        />
      </FormItem>

      <FormItem label="邮箱" name="email">
        <Input
          v-model:value="formData.email"
          placeholder="请输入邮箱"
        />
      </FormItem>

      <FormItem label="手机号" name="phone">
        <Input
          v-model:value="formData.phone"
          placeholder="请输入手机号"
        />
      </FormItem>

      <FormItem label="性别" name="gender">
        <Select
          v-model:value="formData.gender"
          placeholder="请选择性别"
          allow-clear
        >
          <Select.Option :value="1">男</Select.Option>
          <Select.Option :value="2">女</Select.Option>
        </Select>
      </FormItem>

      <FormItem label="状态" name="status">
        <RadioGroup v-model:value="formData.status">
          <Radio :value="1">启用</Radio>
          <Radio :value="0">禁用</Radio>
        </RadioGroup>
      </FormItem>
    </Form>
  </Modal>
</template>
